package com.chenqq.qsocket.mina;

import android.text.TextUtils;
import android.util.Log;

import com.chenqq.qsocket.listener.SocketMessageListener;
import com.chenqq.qsocket.tools.BroadcastUnit;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.subjects.BehaviorSubject;

public class MinaUSocketClient {
    private DatagramSocket datagramSocket;
    private Charset charset = StandardCharsets.UTF_8;
    private int port = 8989;
    private String tag = MinaUSocketClient.class.getSimpleName();
    private BehaviorSubject<String> udpBehaviorSubject;
    private SocketMessageListener socketMessageListener;

    public MinaUSocketClient() {

    }

    public MinaUSocketClient setCharset(Charset charset) {
        this.charset = charset;
        return this;
    }

    public MinaUSocketClient setPort(int port) {
        this.port = port;
        return this;
    }

    public MinaUSocketClient setSocketSendListener(SocketMessageListener socketSendListener) {
        this.socketMessageListener = socketSendListener;
        return this;
    }

    public void sendInfo(String message) {
        if (udpBehaviorSubject == null) {
            udpBehaviorSubject = BehaviorSubject.create();
            Disposable subscribe = udpBehaviorSubject.subscribeOn(Schedulers.io())
                    .map(new Function<String, String>() {
                        @Override
                        public String apply(@NonNull String data) throws Exception {
                            String broadcast = BroadcastUnit.getBroadcast();
                            if (TextUtils.isEmpty(broadcast)) {
                                return "未获取到当前发送广播地址";
                            }
                            if (datagramSocket==null){
                                datagramSocket=new DatagramSocket();
                            }
                            if (!datagramSocket.isConnected()) {
                                InetAddress address = InetAddress.getByName(broadcast);
                                datagramSocket.connect(address, port);
                            }
                            byte[] soServerBytes = data.getBytes(charset);
                            DatagramPacket theOutput = new DatagramPacket(soServerBytes, soServerBytes.length);
                            datagramSocket.send(theOutput);
                            return "Success:" + data;
                        }
                    }).observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<String>() {
                        @Override
                        public void accept(String s) throws Exception {
                            Log.i(tag, "数据发送：" + tag);
                            if (s.startsWith("Success")) {
                                if (socketMessageListener != null) {
                                    socketMessageListener.sendMessageSuccess(tag);
                                }
                            } else {
                                if (socketMessageListener != null) {
                                    socketMessageListener.sendMessageFail(tag, s);
                                }
                            }
                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(Throwable throwable) throws Exception {
                            if (socketMessageListener != null) {
                                socketMessageListener.sendMessageFail(tag, throwable.toString());
                            }
                            stop();
                        }
                    });
        }
        udpBehaviorSubject.onNext(message);
    }


    public void stop() {
        if (datagramSocket != null) {
            datagramSocket.disconnect();
            datagramSocket.close();
            datagramSocket = null;
        }
        if (udpBehaviorSubject != null) {
            udpBehaviorSubject.subscribe().dispose();
            udpBehaviorSubject = null;
        }
    }
}
